﻿using System;
using System.Text.RegularExpressions;
using System.Web;
using System.Web.Configuration;

namespace Slqj.Common
{
    public interface ILoginInfo
    {
        void SaveData(ArcByteSet arcSet);
        void ReadData(ArcByteGet arcGet);
    }

    #region 权限基类
    /// <summary>
    /// 计算权限值
    /// </summary>
    public static class PermissionVal
    {
        public static UInt64 GetAutValueBase0(int permissionBase0)
        {
            UInt64 i = 1;
            return i << permissionBase0;
        }

        public static UInt64 GetAutValueBase1(int permissionBase1)
        {
            if (permissionBase1 <= 0)
                return 0;
            UInt64 i = 1;
            return i << (permissionBase1 - 1);
        }

        public static bool CheckPermission(UInt64 permissionVals, object permissionBase0)
        {
            return (permissionVals & GetAutValueBase1((int)permissionBase0 + 1)) != 0;
        }

        public static bool CheckPermissionBase1(UInt64 permissionVals, object permissionBase1)
        {
            return (permissionVals & GetAutValueBase1((int)permissionBase1)) != 0;
        }
    }
    #endregion

    public static class WebHelper
    {
        #region Http Info
        public static HttpContext Context
        {
            get { return HttpContext.Current; }
        }

        public static HttpRequest Request
        {
            get { return Context.Request; }
        }

        public static HttpResponse Response
        {
            get { return Context.Response; }
        }

        public static System.Web.SessionState.HttpSessionState Session
        {
            get { return Context.Session; }
        }

        public static HttpApplicationState Application
        {
            get { return Context.Application; }
        }

        public static System.Web.Caching.Cache Cache
        {
            get { return Context.Cache; }
        }

        public static string GetResolveReferer()
        {
            string referer = Request.Headers["referer"];
            if (string.IsNullOrEmpty(referer))
                return "";

            string appPath = Request.ApplicationPath;
            if (!appPath[appPath.Length - 1].Equals('/'))
                appPath += "/";

            referer = Regex.Replace(referer, "^https?://[^/:?&]+(?::\\d+)?/", appPath, RegexOptions.IgnoreCase);
            return referer;
        }

        public static bool IsSiteRef
        {
            get
            {
                string referer = Request.Headers["referer"];
                string serverName = Request.ServerVariables["SERVER_NAME"];
                if (string.IsNullOrEmpty(referer) || string.IsNullOrEmpty(serverName))
                    return false;
                Match mres = Regex.Match(referer, "^https?://([^/:?]+)", RegexOptions.IgnoreCase);
                if (!mres.Success)
                    return false;
                return mres.Groups[1].Value.ToLower().Equals(serverName.ToLower());
            }
        }
        #endregion

        #region Page Status Redirect
        const string PAGE403 = "PAGE403";
        const string PAGE404 = "PAGE404";
        const string PAGE500 = "PAGE500";

        public static void EndPage403()
        {
            string url = WebConfigurationManager.AppSettings[PAGE403];
            if(!string.IsNullOrEmpty(url))
            {
                Response.Redirect(Shc.UrlRewrite.RewriterUtils.ResolveUrl(HttpContext.Current.Request.ApplicationPath, url), true);
                return;
            }
            Response.ClearContent();
            Response.StatusCode = 403;
            Response.End();
        }


        public static void EndPage404()
        {
            string url = WebConfigurationManager.AppSettings[PAGE404];
            if (!string.IsNullOrEmpty(url))
            {
                Response.Redirect(Shc.UrlRewrite.RewriterUtils.ResolveUrl(HttpContext.Current.Request.ApplicationPath, url), true);
                return;
            }
            Response.ClearContent();
            Response.StatusCode = 404;
            Response.End();
        }

        public static void EndPage500()
        {
            string url = WebConfigurationManager.AppSettings[PAGE500];
            if (!string.IsNullOrEmpty(url))
            {
                Response.Redirect(Shc.UrlRewrite.RewriterUtils.ResolveUrl(HttpContext.Current.Request.ApplicationPath, url), true);
                return;
            }
            Response.ClearContent();
            Response.StatusCode = 500;
            Response.End();
        }
        #endregion

        #region Login Info
        public const string _permissionSessionKeyPrefix = "LoginInfo_";
        //public const string COOKIE_PWD = "CommonUtility_CO";

        /// <summary>
        /// 设置登录票据
        /// </summary>
        /// <param name="userType">用户身份</param>
        /// <param name="linfo">用户信息</param>
        public static void SetLoginTicket(string userType, ILoginInfo linfo)
        {
            SaveLoginInfo(userType, linfo);
        }

        /// <summary>
        /// 设置登录票据
        /// </summary>
        /// <param name="linfo">用户信息</param>
        public static void SetLoginTicket(ILoginInfo linfo)
        {
            SetLoginTicket(string.Empty, linfo);
        }

        /// <summary>
        /// 保存登录信息
        /// </summary>
        /// <param name="userType">用户身份</param>
        public static void SaveLoginInfo(string userType, ILoginInfo linfo)
        {
            ArcByteSet ascSet = new ArcByteSet();
            linfo.SaveData(ascSet);
            //save cookie
            HttpCookie cookie = new HttpCookie(_permissionSessionKeyPrefix + userType, ascSet.ToBase64());
            cookie.Path = Request.ApplicationPath;
            cookie.Expires = DateTime.MinValue;
            Response.Cookies.Add(cookie);
        }

        /// <summary>
        /// 保存登录信息(默认身份)
        /// </summary>
        public static void SaveLoginInfo(ILoginInfo linfo)
        {
            SaveLoginInfo(string.Empty, linfo);
        }


        /// <summary>
        /// 获取登录信息
        /// </summary>
         /// <param name="linfo">用户信息</param>
        /// <param name="userType">用户身份</param>
        /// <returns>返回登录信息</returns>
        public static T GetUserInfo<T>(string userType)
            where T : ILoginInfo, new()
        {
            string key = _permissionSessionKeyPrefix + userType;
            if (Request.Cookies[key] == null || string.IsNullOrEmpty(Request.Cookies[key].Value))
                return default(T);
            ArcByteGet arcGet = new ArcByteGet(Request.Cookies[key].Value);
            T linfo = new T();
            linfo.ReadData(arcGet);
            return linfo;
        }

        /// <summary>
        /// 获取登录信息(默认身份)
        /// </summary>
        /// <returns>返回登录信息</returns>
        public static T GetUserInfo<T>()
            where T : ILoginInfo, new()
        {
            return GetUserInfo<T>(string.Empty);
        }

        /// <summary>
        /// 登出
        /// </summary>
        /// <param name="userType">用户身份</param>
        public static void Logout(string userType)
        {
            HttpCookie cookie = new HttpCookie(_permissionSessionKeyPrefix + userType, null);
            cookie.Path = Request.ApplicationPath;
            cookie.Expires = DateTime.MinValue;
            Response.Cookies.Add(cookie);
        }

        /// <summary>
        /// 登出(默认身份)
        /// </summary>
        public static void Logout()
        {
            Logout(string.Empty);
        }

        ///// <summary>
        ///// 判断权限
        ///// </summary>
        ///// <param name="userType">用户身份</param>
        ///// <param name="permission">权限对象</param>
        ///// <returns></returns>
        //public static bool CheckPermission(string userType, ILoginInfo linfo, string permissionMember, object permissionBase0)
        //{
        //    ILoginInfo linfo = GetUserInfo(userType);
        //    if (linfo == null)
        //        return false;
        //    UInt64 perVals = linfo.PermissionValue;
        //    return PermissionVal.CheckPermission(perVals, permissionBase0);
        //}

        ///// <summary>
        ///// 判断权限(默认身份)
        ///// </summary>
        ///// <param name="permission"></param>
        ///// <returns></returns>
        //public static bool CheckPermission(object permissionBase0)
        //{
        //    return CheckPermission(string.Empty, permissionBase0);
        //}

        ///// <summary>
        ///// 判断多项权限
        ///// </summary>
        ///// <param name="userType">用户身份</param>
        ///// <param name="permissions">权限对象数组</param>
        ///// <returns></returns>
        //public static bool CheckPermissions(string userType, object[] permissionsBase0)
        //{
        //    foreach (object p in permissionsBase0)
        //        if (!CheckPermission(userType, p))
        //            return false;
        //    return true;
        //}

        ///// <summary>
        ///// 判断多项权限(默认身份)
        ///// </summary>
        ///// <param name="permissions">权限对象数组</param>
        ///// <returns></returns>
        //public static bool CheckPermissions(object[] permissions)
        //{
        //    return CheckPermissions(string.Empty, permissions);
        //}
        #endregion

        #region Cookie id
        const string COOKIE_ID_KEY = "shc_web_helper_cookie_id";

        public static string CookieId
        {
            get
            {
                HttpCookie cookie = Request.Cookies[COOKIE_ID_KEY];
                string cookieId;
                if (cookie == null)
                {
                    cookieId = Guid.NewGuid().ToString("N").ToLower();
                    HttpCookie newCookie = new HttpCookie(COOKIE_ID_KEY, cookieId);
                    newCookie.Path = Request.ApplicationPath;
                    newCookie.Expires = DateTime.MaxValue;
                    Response.Cookies.Add(newCookie);
                }
                else
                    cookieId = cookie.Value;
                return cookieId;
            }
        }
        #endregion
    }
}
